home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / TTYDRIV.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-14  |  13.7 KB  |  640 lines

  1. /* TTY input line editing
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  * split screen by G. J. van der Grinten, PA0GRI
  4.  * fixed split screen ^B and ^W functions - KO4KS
  5.  */
  6. #ifdef MSDOS
  7. #include <conio.h>
  8. #endif
  9. #include "global.h"
  10. #include "ctype.h"
  11. #include "mbuf.h"
  12. #include "session.h"
  13. #include "tty.h"
  14.  
  15. #if !defined(_lint)
  16. static char rcsid[] OPTIONAL = "$Id: ttydriv.c,v 1.16 1997/09/14 14:37:46 root Exp root $";
  17. #endif
  18.  
  19. #ifdef TNOS_68K
  20. extern short UseCurses;
  21. #endif
  22.  
  23. #define    OFF    0
  24. #define    ON    1
  25.  
  26. #ifndef CTLR
  27. #define CTLR    18        /* reprint current line */
  28. #define CTLU    21        /* delete current line in total */
  29. #define    CTLW    23        /* erase last word including preceding space */
  30. #define    CTLZ    26        /* EOF char in dos */
  31. #define    CTLB    02        /* use as F3 in dos but no editing */
  32. #endif
  33.  
  34. extern unsigned char SCREENwidth, SCREENlength;
  35.  
  36. #ifdef ALLSERV
  37.  
  38. static void backspace (void);
  39. static void space (void);
  40. static void switchattr (void);
  41. static void tochatline (struct session * sp, int gothere);
  42. static void fromchatline (struct session * sp);
  43. void clrchatline (struct session * sp);
  44.  
  45. static int Lastsize = 1;
  46. static char Lastline[LINESIZE + 1] = "\n";
  47.  
  48.  
  49. static void
  50. backspace ()
  51. {
  52. int x;
  53.  
  54.     x = wherex ();
  55. #ifdef TNOS_68K
  56.     if (!x && UseCurses)
  57. #else
  58.     if (x == 1)
  59. #endif
  60.         gotoxy (SCREENwidth, wherey () - 1);
  61.     else {
  62. #ifdef TNOS_68K
  63.         if (UseCurses)
  64.             gotoxy (x - 1, wherey ());
  65.         else
  66. #endif
  67.             cputs ("\b");
  68.     }
  69. }
  70.  
  71.  
  72. static void
  73. space ()
  74. {
  75.     cputs (" ");
  76. }
  77.  
  78.  
  79. static void
  80. switchattr ()
  81. {
  82. #if !defined(TNOS_68K) && !defined(UNIX)
  83. struct text_info tr;
  84. unsigned char attr;
  85.  
  86.     gettextinfo (&tr);
  87.     attr = ((tr.attribute & 0x0f) << 4) + ((tr.attribute & 0x70) >> 4);
  88.     textattr (attr);
  89. #endif
  90. #ifdef UNIX
  91.     normvideo ();
  92. #endif
  93. }
  94.  
  95.  
  96. static void
  97. tochatline (sp, gothere)
  98. struct session *sp;
  99. int gothere;
  100. {
  101. #ifndef TNOS_68K
  102.     sp->tsavex = wherex ();
  103.     sp->tsavey = wherey ();
  104.     window (1, SCREENlength - 1, SCREENwidth, SCREENlength);
  105.     switchattr ();
  106.     if (gothere)
  107.         gotoxy (sp->bsavex, sp->bsavey);
  108. #else
  109.     if (UseCurses)
  110.         sp->screen->win = sp->screen->splitwin;
  111. #endif
  112. }
  113.  
  114.  
  115. static void
  116. fromchatline (sp)
  117. struct session *sp;
  118. {
  119. #ifdef TNOS_68K
  120.     if (UseCurses)
  121. #endif
  122.     {
  123.         cputs ("_");
  124.         backspace ();
  125. #ifdef TNOS_68K
  126.         sp->screen->win = sp->screen->textwin;
  127. #else
  128.     }
  129.     sp->bsavex = wherex ();
  130.     sp->bsavey = wherey ();
  131.     window (1, 1 + sp->screen->statline, SCREENwidth, SCREENlength - 2);
  132.     switchattr ();
  133.     gotoxy (sp->tsavex, sp->tsavey);
  134. #endif
  135. }
  136.  
  137.  
  138. void
  139. clrchatline (sp)
  140. struct session *sp;
  141. {
  142.     tochatline (sp, 0);
  143. #ifdef TNOS_68K
  144.     if (UseCurses) {
  145.         werase (sp->screen->win);
  146.         gotoxy (0, 0);
  147.     }
  148. #else
  149.     clrscr ();
  150. #endif
  151.     fromchatline (sp);
  152. }
  153.  
  154.  
  155. /* Accept characters from the incoming tty buffer and process them
  156.  * (if in cooked mode) or just pass them directly (if in raw mode).
  157.  *
  158.  * Echoing (if enabled) is direct to the raw terminal. This requires
  159.  * recording (if enabled) of locally typed info to be done by the session
  160.  * itself so that edited output instead of raw input is recorded.
  161.  * Control-W added by g1emm again.... for word delete.
  162.  * Control-B/Function key 3 added by g1emm for line repeat.
  163.  */
  164.  
  165. struct mbuf *
  166. ttydriv (sp, c)
  167. struct session *sp;
  168. int c;
  169. {
  170. struct mbuf *bp;
  171. char *cp, *rp;
  172. int cnt;
  173.  
  174.     switch (sp->ttystate.edit) {
  175.         case OFF:
  176.             bp = ambufw (1);
  177.             *bp->data = uchar (c);
  178.             bp->cnt = 1;
  179.             if (sp->ttystate.echo) {
  180.                 if (sp->split) {
  181.                     tochatline (sp, 1);
  182. #if defined(TNOS_68K) || defined(UNIX)
  183.                     putch (c);
  184. #else
  185.                     cprintf ("%c", c);
  186. #endif
  187.                     fromchatline (sp);
  188.                 } else {
  189. #if defined(TNOS_68K) || defined(UNIX)
  190.                     putch (c);
  191. #else
  192.                     cprintf ("%c", c);
  193. #endif
  194.                 }
  195.             }
  196. #ifdef TNOS_68K
  197.             rflush ();
  198. #endif
  199.             return bp;
  200.         case ON:
  201.             if (sp->ttystate.line == NULLBUF)
  202.                 sp->ttystate.line = ambufw (LINESIZE);
  203.  
  204.             bp = sp->ttystate.line;
  205.             cp = (char *) (bp->data + bp->cnt);
  206.             /* Perform cooked-mode line editing */
  207.             /* Allow for international character sets - WG7J */
  208.             switch (c) {
  209.                 case '\r':    /* CR and LF both terminate the line */
  210. #ifdef TNOS_68K
  211.                 case '\l':    /* CR and LF both terminate the line */
  212. #else
  213.                 case '\n':
  214. #endif
  215.                     if (sp->ttystate.crnl)
  216.                         *cp = '\n';
  217.                     else
  218.                         *cp = (char) c;
  219.                     if (sp->ttystate.echo) {
  220.                         if (sp->split) {
  221. #ifdef TNOS_68K
  222.                             if (UseCurses) {
  223. #endif
  224.                                 highvideo ();
  225.                                 rp = (char *) bp->data;
  226.                                 while (rp < cp)
  227. #if defined(TNOS_68K) || defined(UNIX)
  228.                                     putch (*rp++);
  229. #else
  230.                                     cprintf ("%c", *rp++);
  231. #endif
  232. #ifdef UNIX
  233.                                 normvideo ();
  234. #else
  235.                                 lowvideo ();
  236. #endif
  237.                                 clreol ();
  238. #ifdef TNOS_68K
  239.                             }
  240. #endif
  241.                             cputs (Eol);
  242.                             clreol ();
  243.                             clrchatline (sp);
  244.                         } else {
  245. #if defined(TNOS_68K) || defined(UNIX)
  246.                             cputs (Eol);
  247. #else
  248.                             cputs (Eol);
  249. #endif
  250.                         }
  251.                     }
  252.                     bp->cnt += 1;
  253.                     sp->ttystate.line = NULLBUF;
  254.                     Lastsize = bp->cnt;
  255.                     memcpy (Lastline, bp->data, (size_t) Lastsize);
  256.                     return bp;
  257.                 case DEL:
  258.                 case '\b':    /* Character delete */
  259.                     if (bp->cnt != 0) {
  260.                         bp->cnt--;
  261.                         if (sp->ttystate.echo) {
  262.                             if (sp->split) {
  263.                                 tochatline (sp, 1);
  264.                                 space ();
  265.                                 backspace ();
  266.                                 backspace ();
  267.                                 fromchatline (sp);
  268.                             } else {
  269.                                 backspace ();
  270.                                 space ();
  271.                                 backspace ();
  272.                             }
  273.                         }
  274.                     }
  275.                     break;
  276.                 case CTLR:    /* print line buffer */
  277.                     if (sp->ttystate.echo) {
  278.                         if (sp->split) {
  279.                             tochatline (sp, 1);
  280. #ifdef TNOS_68K
  281.                             if (UseCurses)
  282.                                 werase (sp->screen->win);
  283. #else
  284.                             clrscr ();
  285. #endif
  286.                             rp = (char *) bp->data;
  287.                             while (rp < cp)
  288. #if defined(TNOS_68K) || defined(UNIX)
  289.                                 putch (*rp++);
  290. #else
  291.                                 cprintf ("%c", *rp++);
  292. #endif
  293.                             fromchatline (sp);
  294.                         } else {
  295. #ifdef UNIX
  296.                             cputs ("^R");
  297.                             cputs (Eol);
  298.                             rp = (char *) bp->data;
  299.                             while (rp < cp)
  300. #if defined(TNOS_68K) || defined(UNIX)
  301.                                 putch (*rp++);
  302. #else
  303.                                 cprintf ("%c", *rp++);
  304. #endif
  305. #else
  306. #ifdef TNOS_68K
  307.                             cnt = bp->cnt;
  308.                             while (cnt != 0) {
  309.                                 cnt--;
  310.                                 if (sp->ttystate.echo) {
  311.                                     backspace ();
  312.                                     space ();
  313.                                     backspace ();
  314.                                 }
  315.                             }
  316. #else
  317. #if defined(UNIX)
  318.                             fprintf (Rawterm, "^R%s", Eol);
  319. #else
  320.                             cprintf ("^R%s", Eol);
  321. #endif
  322. #endif
  323.                             rp = (char *) bp->data;
  324.                             while (rp < cp)
  325. #if defined(TNOS_68K) || defined(UNIX)
  326.                                 putch (*rp++);
  327. #else
  328.                                 cprintf ("%c", *rp++);
  329. #endif
  330. #endif
  331.                         }
  332.                     }
  333.                     break;
  334.                 case CTLU:    /* Line kill */
  335.                     if (sp->split) {
  336.                         clrchatline (sp);
  337.                         bp->cnt = 0;
  338.                     } else {
  339.                         while (bp->cnt != 0) {
  340.                             bp->cnt--;
  341.                             if (sp->ttystate.echo) {
  342.                                 backspace ();
  343.                                 space ();
  344.                                 backspace ();
  345.                             }
  346.                         }
  347.                     }
  348.                     break;
  349.                 case CTLB:    /* Use last line to finish current */
  350.                     if (!sp->split) {
  351.                         cnt = bp->cnt;    /* save count so far */
  352.  
  353.                         while (bp->cnt != 0) {
  354.                             bp->cnt--;
  355.                             if (sp->ttystate.echo) {
  356.                                 backspace ();
  357.                                 space ();
  358.                                 backspace ();
  359.                             }
  360.                         }
  361.                         bp->cnt = (int16) cnt;
  362.                     }
  363.                     if (bp->cnt < (Lastsize - 1)) {
  364.                         memcpy (bp->data + bp->cnt, &Lastline[bp->cnt], (size_t) (Lastsize - 1) - bp->cnt);
  365.                         bp->cnt = (int16) Lastsize - 1;
  366.                     }
  367.                     *(bp->data + bp->cnt) = '\0';    /* make it a string */
  368.                     if (sp->ttystate.echo)
  369.                         if (sp->split) {
  370.                             tochatline (sp, 1);    /* was 0    */
  371. #ifdef TNOS_68K
  372.                             if (UseCurses)
  373.                                 werase (sp->screen->win);
  374. #else
  375.                             clrscr ();
  376. #endif
  377.                             cputs ((char *) bp->data);
  378.                             fromchatline (sp);
  379.                         } else
  380. #if defined(TNOS_68K) || defined(UNIX)
  381.                             cputs ((char *) bp->data);
  382. #else
  383.                             cputs ((char *) bp->data);
  384. #endif
  385.                     break;
  386.                 case CTLW:    /* erase word */
  387.                     if (sp->split)
  388.                         if (sp->ttystate.echo) {
  389.                             tochatline (sp, 1);
  390.                             space ();
  391.                             backspace ();
  392.                         }
  393.                     cnt = 0;    /* we haven't seen a printable char yet */
  394.                     while (bp->cnt != 0) {
  395.                         *(bp->data + bp->cnt--) = '\n';
  396.                         if (sp->ttystate.echo)
  397.                             if (sp->split) {
  398.                                 backspace ();
  399.                                 space ();
  400.                                 backspace ();
  401.                             } else {
  402.                                 backspace ();
  403.                                 space ();
  404.                                 backspace ();
  405.                             }
  406.                         if (isspace ((int) *(bp->data + bp->cnt))) {
  407.                             if (cnt)
  408.                                 break;
  409.                         } else {
  410.                             cnt = 1;
  411.                         }
  412.                     }
  413.                     if (sp->split && sp->ttystate.echo)
  414.                         fromchatline (sp);
  415.                     break;
  416.                 case UPARROW:    /* Recall previous command - WG7J */
  417.                 case DNARROW:    /* Recall next command - WG7J */
  418.                     if (Histry) {
  419.                         /* Blank out what's already there */
  420.                         while (bp->cnt != 0 && sp->ttystate.echo) {
  421.                             bp->cnt--;
  422.                             cputs ("\b \b");
  423.                         }
  424.                         if (c == DNARROW)
  425.                             /* Adjust history */
  426.                             Histry = Histry->next;
  427.                         /* Recall last command */
  428.                         strcpy ((char *) bp->data, Histry->cmd);
  429.                         bp->cnt = (int16) strlen (Histry->cmd);
  430.                         if (c == UPARROW)
  431.                             /* Adjust history */
  432.                             Histry = Histry->prev;
  433.                         /* repaint line */
  434.                         if (sp->ttystate.echo)
  435.                             cputs ((char *) bp->data);
  436.                     }
  437.                     break;
  438.                 default:    /* Ordinary character */
  439.                     *cp = (char) c;
  440.                     bp->cnt++;
  441.  
  442.                     /* ^Z apparently hangs the terminal emulators under
  443.                              * DoubleDos and Desqview. I REALLY HATE having to patch
  444.                              * around other people's bugs like this!!!
  445.                              */
  446.                     if (sp->ttystate.echo &&
  447.                         c != CTLZ &&
  448.                         bp->cnt < LINESIZE - 1) {
  449.                         if (sp->split) {
  450.                             tochatline (sp, 1);
  451. #if defined(TNOS_68K) || defined(UNIX)
  452.                             putch (c);
  453. #else
  454.                             cprintf ("%c", c);
  455. #endif
  456.                             fromchatline (sp);
  457.                         } else {
  458. #if defined(TNOS_68K) || defined(UNIX)
  459.                             putch (c);
  460. #else
  461.                             cprintf ("%c", c);
  462. #endif
  463.                         }
  464.  
  465.                     } else if (bp->cnt >= LINESIZE - 1) {
  466. #if defined(TNOS_68K)
  467.                         putch ('\007');    /* Beep */
  468. #else
  469. #ifdef UNIX
  470.                         write (1, "\007", 1);
  471. #else
  472.                         cputs ("\007");    /* Beep */
  473. #endif
  474. #endif
  475.                         bp->cnt--;
  476.                     }
  477.                     break;
  478.             }
  479.             break;
  480.         default:
  481.             break;
  482.     }
  483. #ifdef TNOS_68K
  484.     rflush ();
  485. #endif
  486.     return NULLBUF;
  487. }
  488.  
  489. #else
  490.  
  491.  
  492. /* Accept characters from the incoming tty buffer and process them
  493.  * (if in cooked mode) or just pass them directly (if in raw mode).
  494.  *
  495.  * Echoing (if enabled) is direct to the raw terminal. This requires
  496.  * recording (if enabled) of locally typed info to be done by the session
  497.  * itself so that edited output instead of raw input is recorded.
  498.  */
  499. struct mbuf *
  500. ttydriv (sp, c)
  501. struct session *sp;
  502. int c;
  503. {
  504. struct mbuf *bp;
  505. char *cp, *rp;
  506.  
  507.     switch (sp->ttystate.edit) {
  508.         case OFF:
  509.             bp = ambufw (1);
  510.             *bp->data = c;
  511.             bp->cnt = 1;
  512.             if (sp->ttystate.echo)
  513. #if defined(TNOS_68K) || defined(UNIX)
  514.                 putch (c);
  515. #else
  516.                 putc (c, Rawterm);
  517. #endif
  518.             return bp;
  519.         case ON:
  520.             if (sp->ttystate.line == NULLBUF)
  521.                 sp->ttystate.line = ambufw (LINESIZE);
  522.  
  523.             bp = sp->ttystate.line;
  524.             cp = bp->data + bp->cnt;
  525.             /* Allow for international character sets - WG7J */
  526.             /* Perform cooked-mode line editing */
  527.             /*        switch(c & 0x7f){ */
  528.             switch (c) {
  529.                 case '\r':    /* CR and LF both terminate the line */
  530.                 case '\n':
  531.                     if (sp->ttystate.crnl)
  532.                         *cp = '\n';
  533.                     else
  534.                         *cp = c;
  535.                     if (sp->ttystate.echo)
  536. #if defined(TNOS_68K) || defined(UNIX)
  537.                         cputs (Eol);
  538. #else
  539.                         fputs (Eol, Rawterm);
  540. #endif
  541.  
  542.                     bp->cnt += 1;
  543.                     sp->ttystate.line = NULLBUF;
  544.                     return bp;
  545.                 case DEL:
  546.                 case '\b':    /* Character delete */
  547.                     if (bp->cnt != 0) {
  548.                         bp->cnt--;
  549.                         if (sp->ttystate.echo)
  550. #if defined(TNOS_68K) || defined(UNIX)
  551.                             cputs ("\b \b");
  552. #else
  553.                             fputs ("\b \b", Rawterm);
  554. #endif
  555.                     }
  556.                     break;
  557.                 case CTLR:    /* print line buffer */
  558.                     if (sp->ttystate.echo) {
  559. #if defined(TNOS_68K) || defined(UNIX)
  560.                         cputs ("^R");
  561.                         cputs (Eol);
  562.                         rp = bp->data;
  563.                         while (rp < cp)
  564.                             putch (*rp++);
  565. #else
  566.                         fprintf (Rawterm, "^R%s", Eol);
  567.                         rp = bp->data;
  568.                         while (rp < cp)
  569.                             putc (*rp++, Rawterm);
  570. #endif
  571.                     }
  572.                     break;
  573.                 case CTLU:    /* Line kill */
  574.                     while (bp->cnt != 0) {
  575.                         bp->cnt--;
  576.                         if (sp->ttystate.echo) {
  577. #if defined(TNOS_68K) || defined(UNIX)
  578.                             cputs ("\b \b");
  579. #else
  580.                             fputs ("\b \b", Rawterm);
  581. #endif
  582.                         }
  583.                     }
  584.                     break;
  585.                 case UPARROW:    /* Recall previous command - WG7J */
  586.                 case DNARROW:    /* Recall next command - WG7J */
  587.                     if (Histry) {
  588.                         /* Blank out what's already there */
  589.                         while (bp->cnt != 0 && sp->ttystate.echo) {
  590.                             bp->cnt--;
  591.                             cputs ("\b \b");
  592.                         }
  593.                         if (c == DNARROW)
  594.                             /* Adjust history */
  595.                             Histry = Histry->next;
  596.                         /* Recall last command */
  597.                         strcpy (bp->data, Histry->cmd);
  598.                         bp->cnt = strlen (Histry->cmd);
  599.                         if (c == UPARROW)
  600.                             /* Adjust history */
  601.                             Histry = Histry->prev;
  602.                         /* repaint line */
  603.                         if (sp->ttystate.echo)
  604.                             cputs (bp->data);
  605.                     }
  606.                     break;
  607.                 default:    /* Ordinary character */
  608.                     *cp = c;
  609.                     bp->cnt++;
  610.  
  611.                     /* ^Z apparently hangs the terminal emulators under
  612.                      * DoubleDos and Desqview. I REALLY HATE having to patch
  613.                      * around other people's bugs like this!!!
  614.                      */
  615.                     if (sp->ttystate.echo &&
  616.                         c != CTLZ &&
  617.                         bp->cnt < LINESIZE - 1) {
  618. #if defined(TNOS_68K) || defined(UNIX)
  619.                         putch (c);
  620. #else
  621.                         putc (c, Rawterm);
  622. #endif
  623.  
  624.                     } else if (bp->cnt >= LINESIZE - 1) {
  625. #if defined(TNOS_68K) || defined(UNIX)
  626.                         write (1, "\007", 1);
  627. #else
  628.                         putc ('\007', Rawterm);    /* Beep */
  629. #endif
  630.                         bp->cnt--;
  631.                     }
  632.                     break;
  633.             }
  634.             break;
  635.     }
  636.     return NULLBUF;
  637. }
  638.  
  639. #endif /*ALLSERV*/
  640.